package utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

public class ProcessExecutor {
    private static final String TAG = "ProcessExecutor";
    private static final long TIMEOUT = 4;

    public String callProcess(String cmd) {
        return callProcess(cmd, null, TIMEOUT);
    }

    public String callProcess(String cmd, File file, long timeOut) {
        StringBuilder sb = new StringBuilder();
        try {
            Process process;
            ProcessBuilder processBuilder = new ProcessBuilder(cmd.split(" "));
            processBuilder.redirectErrorStream(true);
            if (file != null) {
                processBuilder.directory(file);
            }
            try {
                process = processBuilder.start();
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    try {
                        String line;
                        try (BufferedReader outputReader = new BufferedReader(
                                new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
                            while ((line = outputReader.readLine()) != null) {
                                sb.append(line).append(System.lineSeparator());
                            }
                        }
                        try (BufferedReader outputReader = new BufferedReader(
                                new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8))) {
                            boolean isFirstTime = true;
                            while ((line = outputReader.readLine()) != null) {
                                if (isFirstTime) {
                                    isFirstTime = false;
                                    sb.append("ErrorMessage:").append(System.lineSeparator());
                                }
                                sb.append(line).append(System.lineSeparator());
                            }
                        }
                        process.waitFor();
                    } catch (Exception ex) {
                        Log.error(TAG, "process error", ex);
                    }
                });
                future.get(timeOut, TimeUnit.SECONDS);
            } catch (Exception ex) {
                return sb.toString();
            }
        } catch (Exception ex) {
            sb.append("ErrorMessage:").append(System.lineSeparator());
        }
        return sb.toString();
    }
}
